/*! 
 * jquery.align - v 1.0.0 - http://jquery-ux.com/
 * Copyright (c) 2010 Michael Helgeson, Three Dub Media
 * Open Source MIT License - http://jquery-ux.com/license 
 */
// Created: 2008-04-03
// Updated: 2010-02-19
// REQUIRES: jquery

;(function( $ ){ // confine scope

// jquery instance method
$.fn.align = function( target, opts ){
	return this.each(function(){
		// automatically set the position of each element
		$( this ).css( $.align( this, target, opts ) );
		});
	};
	
// jquery static method...
$.align = function( element, target, opts ){
	// extract and rearrange the arguments
	opts = ( opts || target || "center middle" ).toLowerCase().split(" ");
	if ( !target || ( typeof target == "string" && !opts ) ) target = null; 
	// the viewport dimensions
	var win = locate(),
	// the element to move
	elem = locate( element ),
	// the element to compare
	dest = locate( target ),
	// lookup the passed positions	
	top = vertical( opts[1] ),
	left = horizontal( opts[0] );
	// return the aligned top/left positions
	return {
		top: isNaN( top ) ? elem.top : top, 
		left: isNaN( left ) ? elem.left : left
		};
	
	// privledged function for vertical alignments	
	function vertical( str ){
		var limit = win.height + win.top - elem.height, pos;
		switch( str ){
			case 'top':
			case 'top|top': 
			case 'tt':
				return dest.top;
			case 'top|middle':
			case 'tm':
				return dest.top + dest.height/2;
			case 'top|bottom':
			case 'tb':
				return dest.top + dest.height;
			case 'middle|top':
			case 'mt':
				return dest.top - elem.height/2;
			case 'middle':
			case 'middle|middle':
			case 'mm':
				return dest.top + dest.height/2 - elem.height/2;
			case 'middle|bottom':
			case 'mb':
				return dest.top + dest.height - elem.height/2;
			case 'bottom|top':
			case 'bt':
				return dest.top - elem.height;
			case 'bottom|middle':
			case 'bm':
				return dest.top + dest.height/2 - elem.height;
			case 'bottom':
			case 'bottom|bottom':
			case 'bb':
				return dest.top + dest.height - elem.height;
			// auto-adjusted positions	
			case 'outside': 
				pos = vertical('tb');
				return pos < limit ? pos : vertical('bt');
			case 'inside': 
				pos = vertical('bb');
				return pos < limit ? pos : vertical('tt');
			case 'overlap': 
				pos = vertical('mb');
				return pos < limit ? pos : vertical('mt');
			case 'point': 
				pos = vertical('tm');
				return pos < limit ? pos : vertical('bm');	
			// no position
			case 'none': default: return;
			}
		};
		
	// privledged function for hoizontal alignments	
	function horizontal( str ){ 
		var limit = win.width + win.left - elem.width, pos;
		switch( str ){	
			case 'left':
			case 'left|left':
			case 'll':
				return dest.left;
			case 'left|center':
			case 'lc':
				return dest.left + dest.width/2;
			case 'left|right':
			case 'lr':
				return dest.left + dest.width;
			case 'center|left':
			case 'cl':
				return dest.left - elem.width/2;
			case 'center':
			case 'center|center':
			case 'cc':
				return dest.left + dest.width/2 - elem.width/2;
			case 'center|right':
			case 'cr':
				return dest.left + dest.width - elem.width/2;
			case 'right|left':
			case 'rl':
				return dest.left - elem.width;
			case 'right|center': 
			case 'rc':
				return dest.left + dest.width/2 - elem.width;
			case 'right':
			case 'right|right': 
			case 'rr':
				return dest.left + dest.width - elem.width;
			// auto-adjusted positions
			case 'outside':
				pos = horizontal('lr');
				return pos < limit ? pos : horizontal('rl');
			case 'inside': 
				pos = horizontal('rr');
				return pos < limit ? pos : horizontal('ll');
			case 'overlap': 
				pos = horizontal('cr');
				return pos < limit ? pos : horizontal('cl');
			case 'point': 
				pos = horizontal('lc');
				return pos < limit ? pos : horizontal('rc');
			// no position
			case 'none': default: return; 
			}
		};
		
	};
	
// determine the top/left/height/width of an element
function locate( elem ){ 
	var $elem = $( elem ),
	$win = $( window ),
	data = $elem.offset();
	if ( data ) { // element	
		data.width = $elem.outerWidth();
		data.height = $elem.outerHeight(); 
		}
	else data = { // window
		top: $win.scrollTop(),
		left: $win.scrollLeft(),
		width: $win.width(),
		height: $win.height()
		};	
	return data;
	};

})( jQuery ); // secure the $ jQuery alias